/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package luft27.zorcon.ui;

import gov.nasa.worldwind.Configuration;
import gov.nasa.worldwind.Model;
import gov.nasa.worldwind.WorldWind;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.event.RenderingEvent;
import gov.nasa.worldwind.event.RenderingListener;
import gov.nasa.worldwind.event.SelectEvent;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.Layer;
import gov.nasa.worldwind.layers.LayerList;
import gov.nasa.worldwind.layers.MarkerLayer;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwindx.examples.util.HighlightController;
import gov.nasa.worldwindx.examples.util.ToolTipController;
import java.awt.BorderLayout;
import java.awt.Container;
import luft27.propertytree.PropertyNode;
import luft27.propertytree.PropertyTree;
import luft27.propertytree.PropertyValue;

/**
 *
 * @author amalikov
 */
public class MapView {

	public MapView(Container container) {
		this.container = container;
	}
	
	public void show() {
		final String homeDir = System.getProperty("user.dir");
		System.setProperty("sun.awt.noerasebackground", "true");	// This is to stop the AWT canvas from flickering
		System.setProperty("gov.nasa.worldwind.app.config.document", homeDir + "/data/config/worldwind.xml");

        // Specify the configuration file for the elevation model prior to starting World Wind:
        Configuration.setValue(AVKey.EARTH_ELEVATION_MODEL_CONFIG_FILE,
            homeDir + "/data/config/CustomElevationModel.xml");
		
		restoreViewPosition();
	
		wwd = new WorldWindowGLCanvas();
		container.setLayout(new BorderLayout());
		container.add(wwd, BorderLayout.CENTER);
		
		Model m = (Model)WorldWind.createConfigurationComponent(AVKey.MODEL_CLASS_NAME);
		
		StatusLayer status = new StatusLayer();
		status.setEnabled(true);
		status.setEventSource(wwd);
		m.getLayers().add(status);
		
		m.getLayers().getLayerByName("Place Names").setPickEnabled(false);

		wwd.setModel(m);
		
		// create the layers in the right order
		getLayer("Route", "renderable", true);
		getLayer("ActiveLeg", "renderable", true);
		getLayer("Track", "renderable", false);
		getLayer("Vehicle", "marker", true);
		
		vehicle = new Vehicle("/vehicles/vehicle[0]", wwd);

		wwd.addRenderingListener(new RenderingListener(){
			@Override
			public void stageChanged(RenderingEvent event) {
				if (event.getStage().equals(RenderingEvent.AFTER_BUFFER_SWAP)) {
					wwd.removeRenderingListener(this);
					doAfterWwjIsStarted();
				}
			}
		});
		
		// Add controllers to manage highlighting and tool tips.
		toolTipController = new ToolTipController(wwd, AVKey.DISPLAY_NAME, null);
		highlightController = new HighlightController(wwd, SelectEvent.ROLLOVER);
		
		wwd.getSceneController().setDeepPickEnabled(true);
	}
	
	private void doAfterWwjIsStarted() {
		vehicle.bind();
	}

	public void saveViewPosition() {
		PropertyNode s = PropertyTree.INSTANCE.getNode("/settings");
		Position p = wwd.getView().getEyePosition();
		s.set("/map/latitude", new PropertyValue(p.getLatitude().degrees));
		s.set("/map/longitude", new PropertyValue(p.getLongitude().degrees));
		s.set("/map/altitude", new PropertyValue(p.getAltitude()));
		s.set(new PropertyValue(0));
	}
	
	private void restoreViewPosition() {
		PropertyNode s = PropertyTree.INSTANCE.getNode("/settings");
		Configuration.setValue(AVKey.INITIAL_LATITUDE, s.get("/map/latitude").asDouble());
		Configuration.setValue(AVKey.INITIAL_LONGITUDE, s.get("/map/longitude").asDouble());
		Configuration.setValue(AVKey.INITIAL_ALTITUDE, s.get("/map/altitude").asDouble());
	}
	
	private Layer getLayer(String name, String type, boolean picking) {
		if (wwd == null)
			return null;
		
		Layer layer = wwd.getModel().getLayers().getLayerByName(name);

		if (layer == null) {
			switch (type) {
			case "marker":
				layer = new MarkerLayer();
				break;
			case "renderable":
				layer = new RenderableLayer();
				break;
			}
			
			if (layer != null) {
				layer.setName(name);
				layer.setPickEnabled(picking);
				insertLayer(layer);
			}
		}
		
		return layer;
	}
	

	/**
	 * Inserts layer before PlaceNames layer for right rendering order.
	 */
	private void insertLayer(Layer layer) {
		LayerList list = wwd.getModel().getLayers();
		list.add(list.indexOf(list.getLayerByName("Place Names")), layer);
	}
	
	private final Container container;
	private WorldWindowGLCanvas wwd;
	private Vehicle vehicle;
	private ToolTipController toolTipController;
	private HighlightController highlightController;	
}
